﻿ 
using System;
using System.Web.Mvc;
using System.Web.Security;
using CarTrackr.Controllers;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;


namespace CarTrackr.Tests.Controllers
{
    
    [TestClass]
    public class AccountControllerTest
    {
        

    
        [TestMethod]
        public void TestRegisterWithEmptyEntries()
        {

              AccountController target = new AccountController();

              ViewResult result = target.Register(null, null, null, null) as ViewResult;

              Assert.IsFalse(target.ModelState.IsValid);

            Assert.AreEqual("Register", result.ViewName); 
        }



        [TestMethod]
        public void RegisterWithEmptyUserName()
        {

            AccountController target = new AccountController();
           
   
            // Execute
            string username = "";
            string email = "test@example.com";
            string password = "testing123";
            string confirmPassword = "testing123";

            ViewResult result = target.Register(username, email, password, confirmPassword) as ViewResult;

            // Verify
            ViewDataDictionary viewData = result.ViewData;
            Assert.AreEqual("Register", result.ViewName);
            Assert.IsFalse(viewData.ModelState.IsValid);
            Assert.AreEqual(1, viewData.ModelState.Count);

            Assert.AreEqual("You must specify a username.", viewData.ModelState["username"].Errors[0].ErrorMessage);


        }


        [TestMethod]
        public void RegisterTesWithValidEntries()
        {

            var formsAuthenticationMock = new Mock<IFormsAuthentication>();
            var membershipProviderMock = new Mock<MembershipProvider>();

            formsAuthenticationMock.Setup(f => f.SetAuthCookie(It.IsAny<string>(), It.IsAny<bool>())).AtMostOnce(); 


            MembershipCreateStatus status = MembershipCreateStatus.Success;
            membershipProviderMock
                .Setup(m => m.CreateUser(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>(), true, It.IsAny<object>(), out status))
                .Returns(new MembershipUser("AspNetSqlMembershipProvider", "", null, "", "", "", true, false, DateTime.Now, DateTime.Now, DateTime.Now, DateTime.Now, DateTime.MinValue));

            AccountController target = new AccountController(formsAuthenticationMock.Object,membershipProviderMock.Object);
         
            // Execute
            string username = "testing";
            string email = "test@example.com";
            string password = "testing123";
            string confirmPassword = "testing123";

            RedirectToRouteResult result = target.Register(username, email, password, confirmPassword) as RedirectToRouteResult;

            Assert.AreEqual("Index", result.RouteValues["Action"]);
            Assert.AreEqual("Home", result.RouteValues["Controller"]);


        }

        [TestMethod]
        public void LogoutTest()
        {
            // Setup
            var formsAuthenticationMock = new Mock<IFormsAuthentication>();
            var membershipProviderMock = new Mock<MembershipProvider>();

             formsAuthenticationMock.Setup(f => f.SignOut()).AtMostOnce(); 

            AccountController target = new AccountController(formsAuthenticationMock.Object, membershipProviderMock.Object);
        
            // Execute
            RedirectToRouteResult result = target.Logout() as RedirectToRouteResult;

            Assert.AreEqual("Index", result.RouteValues["Action"]);
            Assert.AreEqual("Home", result.RouteValues["Controller"]);
        }

        [TestMethod]
        public void LoginWithEmptyEntries()
        {
            // Setup
            var formsAuthenticationMock = new Mock<IFormsAuthentication>();
            var membershipProviderMock = new Mock<MembershipProvider>();

            AccountController target = new AccountController(formsAuthenticationMock.Object,
                                                             membershipProviderMock.Object);

            // Execute
            ViewResult result = target.Login(null, null, null) as ViewResult;


            Assert.AreEqual("Login", result.ViewName);
        }


          [TestMethod]
          public void LoginWithIncorrectLoginAccount()
          {
                  
                var formsAuthenticationMock = new Mock<IFormsAuthentication>();
                var membershipProviderMock = new Mock<MembershipProvider>();

                formsAuthenticationMock.Setup(f => f.SetAuthCookie(It.IsAny<string>(), true)).AtMost(0);

                membershipProviderMock
                .Setup(m => m.ValidateUser(It.IsAny<string>(), It.IsAny<string>()))
                .Returns(false);

                AccountController target = new AccountController(formsAuthenticationMock.Object, membershipProviderMock.Object);

                ViewResult result = target.Login("test", "test", null) as ViewResult;
                ViewDataDictionary viewData = result.ViewData;
               
                Assert.AreEqual("Login", result.ViewName);
                Assert.IsFalse(viewData.ModelState.IsValid);
                Assert.AreEqual(1, viewData.ModelState.Count);

          }


          [TestMethod]
          public void LoginWithCorrectLoginAccount()
          {
              // Setup
              var formsAuthenticationMock = new Mock<IFormsAuthentication>();
              var membershipProviderMock = new Mock<MembershipProvider>();

              formsAuthenticationMock.Setup(f => f.SetAuthCookie(It.IsAny<string>(), true)).AtMostOnce();

              membershipProviderMock
                  .Setup(m => m.ValidateUser(It.IsAny<string>(), It.IsAny<string>()))
                  .Returns(true);

              AccountController target = new AccountController(formsAuthenticationMock.Object, membershipProviderMock.Object);
         
              // Execute
              string username = "testing";
              string password = "testing123";
              Nullable<bool> rememberMe = true;

              // Execute
              RedirectToRouteResult result = target.Login(username, password, rememberMe) as RedirectToRouteResult;

              Assert.AreEqual("Index", result.RouteValues["Action"]);
              Assert.AreEqual("Home", result.RouteValues["Controller"]);
          }



    }
}

